package br.unicamp.ic.sgct.server.dominio.servicos;

import it.biobytes.ammentos.Ammentos;
import it.biobytes.ammentos.PersistenceException;
import it.biobytes.ammentos.query.SqlQueryFilter;

import java.util.ArrayList;
import java.util.List;

import br.unicamp.ic.sgct.client.aplicacao.ucs.inscricao.InscricaoService;
import br.unicamp.ic.sgct.client.dominio.exception.InfraException;
import br.unicamp.ic.sgct.client.dominio.to.InscricaoTO;
import br.unicamp.ic.sgct.client.dominio.to.SessaoTO;
import br.unicamp.ic.sgct.client.dominio.to.UsuarioTO;
import br.unicamp.ic.sgct.server.dominio.entidades.Inscricao;
import br.unicamp.ic.sgct.server.dominio.entidades.Usuario;
import br.unicamp.ic.sgct.server.recursos.persistencia.AmmentosConnection;

import com.google.gwt.user.server.rpc.RemoteServiceServlet;

/**
 * alterada
 * The server side implementation of the RPC service.
 */
@SuppressWarnings("serial")
public class InscricaoServiceImpl extends RemoteServiceServlet implements
		InscricaoService {

	public void inscrever(UsuarioTO usuario) throws InfraException {
		List<Usuario> lstUsuario;
		
		System.out
				.println("\nInscricaoServiceImpl :: inscrever(Usuario) acionado");

		try {
			Usuario usuarioPersist = new Usuario(usuario);
			
			AmmentosConnection.instance();
			
			//INICIO - EXERC. 4
			
			List<SessaoTO> sessoesLotadas = new ArrayList<SessaoTO>();
			for (InscricaoTO inscricao : usuario.getInscricaoList()) {
				SessaoTO sessaoTo = inscricao.getSessao();
				List<Inscricao> lstInscricoes = Ammentos.load(Inscricao.class, 
						new SqlQueryFilter("id_sessaoconf = " + sessaoTo.getId() + " and situacao = 1"));
				
				if (lstInscricoes.size() >= sessaoTo.getSala().getCapacidade()) {
					sessoesLotadas.add(sessaoTo);
					
				}
				
			}
			
			if (!sessoesLotadas.isEmpty()) {
				StringBuilder mensagem = new StringBuilder();
				mensagem.append("Não há mais vagas para o(s) evento(s) selecionado(s): [");
				for (SessaoTO sessaoTo : sessoesLotadas) {
					mensagem.append(sessaoTo.getTema() + " - " + sessaoTo.getData() + ", ");
					
				}
				mensagem.replace(mensagem.length() - 2, mensagem.length(), "].");
				mensagem.append(" Favor selecionar outro(s) de seu interesse.");
				
				throw new InfraException(mensagem.toString());
				
			}
			
			//FIM - EXERC. 4

			lstUsuario = Ammentos.load(Usuario.class,
					new SqlQueryFilter("email like '" + usuarioPersist.getEmail() + 
							"'"));

			Ammentos.openTransaction();
			
			// Se o usuário não existia no banco de dados, insira-o normalmente
			if (lstUsuario != null && lstUsuario.isEmpty()) {

				Ammentos.save( usuarioPersist.getPessoa() );
				Ammentos.save(usuarioPersist);
	
			}
			// Se um usuário foi encontrado, execute um update adicionando
			// os eventos que o usuário se inscreveu, desde que o usuário já
			// não tenha se inscrito no evento ou esteja com a inscrição cancelada
			if (lstUsuario != null && !lstUsuario.isEmpty() ) {
				
				//INICIO - EXERC. 4
				
				List<Inscricao> inscricaoList = new ArrayList<Inscricao>();
				StringBuilder erros = new StringBuilder();
				
				for (Inscricao inscricao : usuarioPersist.getInscricaoList()) {
					boolean found = false;
					
					for (Inscricao inscricaoFeita : lstUsuario.get(0).getInscricaoList()) {
						if (inscricao.getSessao().getId() == inscricaoFeita.getSessao().getId()) {
							if (inscricaoFeita.getSituacao() == 3) {
								inscricaoFeita.setSituacao(0);
								inscricaoList.add(inscricaoFeita);
								found = true;
								break;
								
							} else {
								erros.append(inscricaoFeita.getSessao().getTema() + ", ");
								break;
								
							}
							
						}
						
					}
					
					if (!found) {
						inscricaoList.add(inscricao);
						
					}
					
				}
				
				// Verifica se o usuário já estava inscrito em algum evento
				if (erros.length() > 0) {
					erros.replace(erros.length() - 2, erros.length(), "");
					throw new InfraException("Usu\u00e1rio j\u00e1 est\u00e1 " +
						"inscrito para o(s) evento(s): " + erros.toString() + "!");
					
				}
				
				// Atualiza a lista de inscrições do Usuário
				lstUsuario.get(0).setInscricaoList(inscricaoList);
				
				//FIM - EXERC. 4
				
				Ammentos.save ( lstUsuario.get(0) );
				Ammentos.save ( lstUsuario.get(0).getPessoa() );

			}
			Ammentos.commitTransaction();

		}
		catch (PersistenceException e) {
			throw new InfraException("InfraException: " + e.getMessage());
		}
	}
}